﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Drawing.Text;
using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Windows.ApplicationModel;
using Windows.UI;
using WinUIEditor;

using MicrosoftFontFamily = Microsoft.UI.Xaml.Media.FontFamily;
using DrawingFontFamily = System.Drawing.FontFamily;
using Windows.Networking;


namespace DevCangjie.utils.Settings
{
    // 自定义 JsonConverter 用于 FontFamily 类型
    internal class FontFamilyJsonConverter : JsonConverter<FontFamily>
    {
        public override FontFamily Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.String)
            {
                // JSON 中是一个字符串，直接读取
                string fontName = reader.GetString();
                return new FontFamily(fontName);
            }
            else if (reader.TokenType == JsonTokenType.StartObject)
            {
                // JSON 中是一个对象，读取其中的 "Source" 属性
                string fontName = null;

                while (reader.Read())
                {
                    if (reader.TokenType == JsonTokenType.PropertyName)
                    {
                        string propertyName = reader.GetString();

                        if (propertyName.Equals("Source", StringComparison.OrdinalIgnoreCase))
                        {
                            reader.Read(); // 移到属性值
                            fontName = reader.GetString();
                        }
                        else
                        {
                            // 如果有其他属性，跳过其值
                            reader.Skip();
                        }
                    }
                    else if (reader.TokenType == JsonTokenType.EndObject)
                    {
                        break;
                    }
                }

                if (!string.IsNullOrEmpty(fontName))
                {
                    return new FontFamily(fontName);
                }
                else
                {
                    throw new JsonException("无法从 JSON 中读取 FontFamily 对象的 'Source' 属性。");
                }
            }
            else
            {
                throw new JsonException($"无法从 JSON 令牌类型 '{reader.TokenType}' 创建 FontFamily 对象。");
            }
        }

        public override void Write(Utf8JsonWriter writer, FontFamily value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.Source);
        }
    }

    public class Settings
    {
        // 定义加载失败事件
        public event EventHandler<string>? OnLoadFailed;
        public static InstalledFontCollection GetSystemFonts { get; set; } = new InstalledFontCollection();
        public static System.Drawing.FontFamily[] AllFonts { get; set; } = GetSystemFonts.Families;

        // 是否显示欢迎页面
        public bool IsWelcomePageShown { get; set; } = true;

        // 字体和字号设置 for different styles

        // 默认样式 - STYLE_DEFAULT
        public FontFamily StyleDefaultFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleDefaultFontSize { get; set; } = 14;

        // 行号样式 - STYLE_LINENUMBER
        public FontFamily StyleLineNumberFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleLineNumberFontSize { get; set; } = 14;

        // 括号样式 - STYLE_BRACELIGHT
        public FontFamily StyleBraceLightFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleBraceLightFontSize { get; set; } = 14;

        // 刷新错误（括号错误）样式 - STYLE_BRACEBAD
        public FontFamily StyleBraceBadFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleBraceBadFontSize { get; set; } = 14;

        // 控制字体样式 - STYLE_CONTROLCHAR
        public FontFamily StyleControlCharFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleControlCharFontSize { get; set; } = 14;

        // 缩进样式 - STYLE_INDENTGUIDE
        public FontFamily StyleIndentGuideFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleIndentGuideFontSize { get; set; } = 14;

        // 呼叫提示样式 - STYLE_CALLTIP
        public FontFamily StyleCallTipFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleCallTipFontSize { get; set; } = 14;

        // 折叠显示文本样式 - STYLE_FOLDDISPLAYTEXT
        public FontFamily StyleFoldDisplayTextFont { get; set; } = new FontFamily("Cascadia Code");
        public int StyleFoldDisplayTextFontSize { get; set; } = 14;

        // 控制台字体
        public FontFamily ConsoleFont { get; set; } = new FontFamily("Consolas");

        // 控制台字体大小
        public double ConsoleSize { get; set; } = 14;

        // 是否使用集成终端
        public bool RunProgramInIntegratedTerminal { get; set; } = false;

        // 编辑器行间距
        public int TextLineSpacing { get; set; } = 18;

        // 注释格式
        public string CommentFormat { get; set; } = "// *";
 
        // 主题
        public enum Theme
        {
            Light,
            Dark,
            SystemDefault
        }

        // 环境变量
        public string CangjiePath { get; set; } = Path.Combine(Package.Current.InstalledLocation.Path, "Compiler", "cangjie0.53.13");

        // 字符集
        public string CharSet { get; set; } = "UTF-8";

        protected Theme _currentTheme = Theme.Light;
        public Theme CurrentTheme
        {
            get => _currentTheme;
            private set
            {
                if (_currentTheme != value)
                {
                    _currentTheme = value;
                    OnThemeChanged?.Invoke(null, EventArgs.Empty);
                }
            }
        }
        public event EventHandler OnThemeChanged;

        // 基于当前主题的默认文本颜色

        /// <summary>
        /// 更新当前主题
        /// </summary>
        /// <param name="newTheme">新的主题</param>
        public void UpdateTheme(Theme newTheme)
        {
            CurrentTheme = newTheme;
            DefaultTextColor = CurrentTheme switch
            {
                Theme.Light => Colors.Black,
                Theme.Dark => Colors.White,
                _ => Colors.Black
            };
        }
        // 默认文本颜色
        public Color DefaultTextColor { get; set; }

        // 定义高亮规则类型
        public enum HighlightRuleType
        {
            Regular,
            LineComment
        }

        // 定义高亮规则
        public class HighlightRule
        {
            public HighlightRuleType RuleType { get; set; }
            public required string Pattern { get; set; }
            public Color Color { get; set; }
            public bool Bold { get; set; }
            public int Priority { get; set; } 
        }
        // 高亮规则列表

        public List<HighlightRule> HighlightRules = new List<HighlightRule>
        {
            new HighlightRule 
            { 
                Pattern = @"//.*", 
                Color = Color.FromArgb(0xFF, 0x00, 0x80, 0x00), 
                Bold = false, 
                RuleType = HighlightRuleType.LineComment,
                Priority = 1 
            }, 

            new HighlightRule 
            { 
                Pattern = @"\bclass\b", 
                Color = Color.FromArgb(0xFF, 0xFF, 0xC0, 0xCB), 
                Bold = true, 
                RuleType = HighlightRuleType.Regular,
                Priority = 3 
            }, 

            new HighlightRule 
            { 
                Pattern = @"\bpublic\b", 
                Color = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00), 
                Bold = true, 
                RuleType = HighlightRuleType.Regular,
                Priority = 2 
            }, 

            new HighlightRule 
            { 
                Pattern = @"\bprivate\b", 
                Color = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00), 
                Bold = true, 
                RuleType = HighlightRuleType.Regular,
                Priority = 2 
            }, 

            new HighlightRule 
            { 
                Pattern = @"\bdefault\b", 
                Color = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00), 
                Bold = true, 
                RuleType = HighlightRuleType.Regular,
                Priority = 2 
            },  

            new HighlightRule 
            { 
                Pattern = @"\bmain\b", 
                Color = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00), 
                Bold = true, 
                RuleType = HighlightRuleType.Regular,
                Priority = 4 
            }, 

            new HighlightRule 
            { 
                Pattern = @"\bfn\b", 
                Color = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00), 
                Bold = true, 
                RuleType = HighlightRuleType.Regular,
                Priority = 2 
            },
            new HighlightRule 
            { 
                Pattern = @"\b(as|abstract|break|Bool|case|catch|class|const|continue|Rune|do|else|enum|extend|for|func|false|finally|foreign|Float16|Float32|Float64|if|in|is|init|import|interface|Int8|Int16|Int32|Int64|IntNative|let|mut|main|macro|match|Nothing|open|operator|override|prop|public|package|private|protected|quote|redef|return|spawn|super|static|struct|synchronized|try|this|true|type|throw|This|unsafe|Unit|UInt8|UInt16|UInt32|UInt64|UIntNative|var|VArray|where|while)\b",
                Color = Color.FromArgb(0, 216, 160, 223), 
                Bold = false, 
                RuleType = HighlightRuleType.Regular,
                Priority = 5 
            }
        };
    
        public static Settings Instance { get; set; } = new Settings();

        protected Settings()
        {
            // As you can see, there is nothing here. 
        }

        internal class SettingsDto : Settings
        {
            // As you can see, there is nothing here. 
        }

        /// <summary>
        /// 保存设置到 Settings.json 文件
        /// </summary>
        public void Save()
        {
            try
            {
                string jsonString = JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
                string exePath = AppContext.BaseDirectory;
                string filePath = Path.Combine(exePath, "Settings.json");
                File.WriteAllText(filePath, jsonString, System.Text.Encoding.UTF8);
            }
            catch (Exception ex)
            {
                // 处理保存时的异常（可记录日志或提示用户）
                Console.WriteLine($"保存设置时出错: {ex.Message}");
            }
        }

        public void SaveDefaultSettings()
        {
            try
            {
                string jsonString = JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
                string exePath = AppContext.BaseDirectory;
                string filePath = Path.Combine(exePath, "Resources", "DefaultSettings.json");
                File.WriteAllText(filePath, jsonString, System.Text.Encoding.UTF8);
            }
            catch (Exception ex)
            {
                // 处理保存时的异常（可记录日志或提示用户）
                Console.WriteLine($"保存默认设置时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 从 Settings.json 文件加载设置
        /// </summary>
        public void Load(string filePath)
        {
            try
            {
                string exePath = AppContext.BaseDirectory;
                //string filePath = Path.Combine(exePath, "Settings.json");
                if (File.Exists(filePath))
                {
                    var options = new JsonSerializerOptions
                    {
                        Converters =
                        {
                            new FontFamilyJsonConverter()
                        }
                    };
                    string jsonString = File.ReadAllText(filePath, System.Text.Encoding.UTF8);
                    var loadedSettings = JsonSerializer.Deserialize<SettingsDto>(jsonString, options);
                    if (loadedSettings != null)
                    {
                        // 将加载的设置复制到当前实例
                        this.CopyFrom(loadedSettings);
                    }
                }
                else
                {
                    // 文件不存在，创建一个空的设置文件
                    File.WriteAllText(filePath, "{}", System.Text.Encoding.UTF8);
                }
            }
            catch (Exception ex)
            {
                // 处理加载时的异常（可记录日志或提示用户）
                Console.WriteLine($"加载设置时出错: {ex.Message}");

                // 记录错误信息到debug.log
                LogError($"加载设置时出错: {ex}");

                // 触发加载失败事件
                OnLoadFailed?.Invoke(this, ex.Message);

                throw;
            }
        }

        private void LogError(string message)
        {
            try
            {
                string exePath = AppContext.BaseDirectory;
                string logDirectory = Path.Combine(exePath, "Logs");

                // 如果日志目录不存在，则创建
                if (!Directory.Exists(logDirectory))
                {
                    Directory.CreateDirectory(logDirectory);
                }

                string logFilePath = Path.Combine(logDirectory, "debug.log");

                // 构建日志内容，包含时间戳
                string logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}{Environment.NewLine}";

                // 将日志内容追加到日志文件
                File.AppendAllText(logFilePath, logMessage, Encoding.UTF8);
            }
            catch
            {
                // 如果日志记录失败，可以选择忽略，避免抛出异常
            }
        }

        protected void CopyFrom(Settings other)
        {
            this.IsWelcomePageShown = other.IsWelcomePageShown;
            this.StyleDefaultFont = other.StyleDefaultFont;
            this.StyleDefaultFontSize = other.StyleDefaultFontSize;
            this.StyleLineNumberFont = other.StyleLineNumberFont;
            this.StyleLineNumberFontSize = other.StyleLineNumberFontSize;
            this.StyleBraceLightFont = other.StyleBraceLightFont;
            this.StyleBraceLightFontSize = other.StyleBraceLightFontSize;
            this.StyleBraceBadFont = other.StyleBraceBadFont;
            this.StyleBraceBadFontSize = other.StyleBraceBadFontSize;
            this.StyleControlCharFont = other.StyleControlCharFont;
            this.StyleControlCharFontSize = other.StyleControlCharFontSize;
            this.StyleIndentGuideFont = other.StyleIndentGuideFont;
            this.StyleIndentGuideFontSize = other.StyleIndentGuideFontSize;
            this.StyleCallTipFont = other.StyleCallTipFont;
            this.StyleCallTipFontSize = other.StyleCallTipFontSize;
            this.StyleFoldDisplayTextFont = other.StyleFoldDisplayTextFont;
            this.StyleFoldDisplayTextFontSize = other.StyleFoldDisplayTextFontSize;

            this.ConsoleFont = other.ConsoleFont;
            this.ConsoleSize = other.ConsoleSize;
            this.RunProgramInIntegratedTerminal = other.RunProgramInIntegratedTerminal;
            this.TextLineSpacing = other.TextLineSpacing;
            this.CommentFormat = other.CommentFormat;
            this.CangjiePath = other.CangjiePath;
            this.CharSet = other.CharSet;

            this.CurrentTheme = other.CurrentTheme;
            this.DefaultTextColor = other.DefaultTextColor;
            this.HighlightRules = other.HighlightRules;
        }

    }

    
}
